package com.huawei.codearts.dao;


import com.huawei.codearts.tools.utils.JedisPoolUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.params.SetParams;

import java.util.Map;

@Slf4j
@Repository
public class RedisUtilsDao {

    public static String set(String key, String val) {
        Jedis jedis = JedisPoolUtils.getJedis();
//        System.out.println("jedis = " + jedis);
        String ok = null;
        try {
            // 存入数据
            ok = jedis.set(key, val);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (jedis != null)
                jedis.close();
        }

        return ok;
    }

    public static String setNxEx(String key, String val, int expiration) {
        Jedis jedis = JedisPoolUtils.getJedis();
        String ok = null;
        try {
            // 使用SetParams设置参数
            SetParams setParams = new SetParams();
            setParams.ex((long)expiration); // 设置键的过期时间（ex秒 px毫秒）
            setParams.nx();
            // 使用Jedis和SetParams设置值
            ok = jedis.set(key, val, setParams);
//            ok = jedis.set(key, val, "NX", "EX", expiration);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (jedis != null)
                jedis.close();
        }

        return ok;
    }

    public static String setNxExLua(String key, String val, int expiration) {
        Jedis jedis = JedisPoolUtils.getJedis();
        String ok = null;
        try {
            // Lua脚本 设置键值对的同时指定过期时间（秒）
//            String script = "local isExists = redis.call('exists', KEYS[1]) " +
//                    "if isExists == 0 then " +
//                    "    redis.call('set', KEYS[1], ARGV[1]) " +
//                    "    redis.call('expire', KEYS[1], ARGV[2]) " +
//                    "    return 1 " +
//                    "else " +
//                    "    return 0 " +
//                    "end";
            String script = "if redis.call('setnx', KEYS[1], ARGV[1]) == 1 then " +
                    "   redis.call('expire', KEYS[1], ARGV[2]) " +
                    "   return 1 " +
                    "else " +
                    "   return 0 " +
                    "end";
            Long result = (Long) jedis.eval(
                    script,
                    // 键的数量
                    1,
                    // 键本身
                    key,
                    // 值
                    val,
                    // 过期时间
                    String.valueOf(expiration)
            );
            if (result == 1L) {
                ok = "ok";
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (jedis != null)
                jedis.close();
        }

        return ok;
    }

    public static String setex(String key, String val, int expiration) {
        Jedis jedis = JedisPoolUtils.getJedis();
        String ok = null;
        try {
            // 设置键值对的同时指定过期时间（秒）
            ok = jedis.setex(key, expiration, val);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (jedis != null)
                jedis.close();
        }

        return ok;
    }

    public static String get(String key) {
        Jedis jedis = JedisPoolUtils.getJedis();
        String data = null;
        try {
            // 获取数据
            data = jedis.get(key);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (jedis != null)
                jedis.close();
        }
        return data;
    }

    public static Long del(String key) {
        Jedis jedis = JedisPoolUtils.getJedis();
        Long result = null;
        try {
            // 删除数据
            result = jedis.del(key);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (jedis != null)
                jedis.close();
        }
        return result;
    }

    public static Long hset(String key, String field, String value) {
        Jedis jedis = JedisPoolUtils.getJedis();
        Long result = null;
        try {
            // 插入hash数据
            result = jedis.hset(key,field,value);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (jedis != null)
                jedis.close();
        }
        return result;
    }

    public static Map<String, String> hgetAll(String key) {
        Jedis jedis = JedisPoolUtils.getJedis();
        Map<String, String> data = null;
        try {
            // 获取所有hash数据并输出
            data = jedis.hgetAll(key);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (jedis != null)
                jedis.close();
        }
        return data;
    }


    // redis加锁
    public static boolean lock(String key, String uuid, int expiration) {
        String result = RedisUtilsDao.setNxExLua(key, uuid,  expiration);
        return "OK".equals(result);
    }

    // redis lua删除锁
    public static void unlock(String key, String uuid) {
        Jedis jedis = JedisPoolUtils.getJedis();
        // Lua脚本，用于设置key的值
//        String luaScript = "return redis.call('SET', KEYS[1], ARGV[1])";
//        String luaScript = "return redis.call('GET', KEYS[1])";
        String luaScript = "if redis.call('GET',KEYS[1]) == ARGV[1] " +
                "then " +
                "return redis.call('DEL',KEYS[1]) " +
                "else " +
                "return 0 " +
                "end";
        // 使用Lua脚本设置key
        Object result = jedis.eval(luaScript, 1, key, uuid);
        System.out.println("Lua script executed, result: " + result);
    }

}
